package com.zenchn.service.impl;

import com.zenchn.dao.TSysDictMapper;
import com.zenchn.dao.TSysDictTypeMapper;
import com.zenchn.dynamic.TSysDictDynamicMapper;
import com.zenchn.dynamic.TSysDictTypeDynamicMapper;
import com.zenchn.generic.GenericDao;
import com.zenchn.generic.GenericServiceImpl;
import com.zenchn.model.TSysDict;
import com.zenchn.model.TSysDictExample;
import com.zenchn.model.TSysDictType;
import com.zenchn.entity.TSysDictVO;
import com.zenchn.service.DictService;
import org.springframework.beans.BeanUtils;
import javax.annotation.Resource;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import static org.mybatis.dynamic.sql.SqlBuilder.*;
//import static com.zenchn.dynamic.TSysDictDynamicSqlSupport.*;
/**
 * 数据字典 业务实现类
 *
 * @author dingxinfa
 * @date 2020-04-16
 **/
@Service
@Transactional(rollbackFor = Exception.class)
public class DictServiceImpl  extends GenericServiceImpl<TSysDict, String, TSysDictExample> implements DictService {

    @Resource
    private TSysDictTypeMapper dictTypeMapper;

    @Resource
    private TSysDictMapper dictMapper;

    @Resource
    private TSysDictTypeDynamicMapper dictTypeDynamicMapper;

    @Resource
    private TSysDictDynamicMapper dictDynamicMapper;


    @Override
    public GenericDao<TSysDict, String, TSysDictExample> getDao() {
        return dictMapper;
    }


    /***
     * 整合数据字典级联查询 搜索条件
     * @param parentId  上级字典ID
     * @param dictTypeId  数据字典类型ID
     * @param keyword  关键字 字典名称 字典编码 字典值
     * @param isEnable  是否启用
     * @return
     */
    private TSysDictExample selectCascadeListDictExample(String parentId, String dictTypeId, String keyword, Boolean isEnable) {

        TSysDictExample example=new TSysDictExample();
        TSysDictExample.Criteria criteria=example.createCriteria();

        if (null!=keyword && !"".equals(keyword.trim())){
            TSysDictExample.Criteria criteria2=example.createCriteria();
            TSysDictExample.Criteria criteria3=example.createCriteria();

            criteria.andDictNameLike("%"+keyword.trim()+"%");
            criteria2.andDictCodeLike("%"+keyword.trim()+"%");
            criteria3.andDictValueLike("%"+keyword.trim()+"%");

            if (null!=dictTypeId && !"".equals(dictTypeId.trim())){
                criteria.andDictTypeIdEqualTo(dictTypeId.trim());
                criteria2.andDictTypeIdEqualTo(dictTypeId.trim());
                criteria3.andDictTypeIdEqualTo(dictTypeId.trim());
            }
            if (null!=isEnable){
                criteria.andIsEnableEqualTo(isEnable);
                criteria2.andIsEnableEqualTo(isEnable);
                criteria3.andIsEnableEqualTo(isEnable);
            }


            if (null!=parentId && !"".equals(parentId.trim())) {
                criteria.andParentIdEqualTo(parentId.trim());
                criteria2.andParentIdEqualTo(parentId.trim());
                criteria3.andParentIdEqualTo(parentId.trim());
            }else{
                criteria.andDataLevelEqualTo(1);
                criteria2.andDataLevelEqualTo(1);
                criteria3.andDataLevelEqualTo(1);
            }

            example.or(criteria2);
            example.or(criteria3);
        }else{
            if (null!=dictTypeId && !"".equals(dictTypeId.trim())) {
                criteria.andDictTypeIdEqualTo(dictTypeId.trim());
            }
            if (null!=isEnable){
                criteria.andIsEnableEqualTo(isEnable);
            }
            if (null!=parentId && !"".equals(parentId.trim())) {
                criteria.andParentIdEqualTo(parentId.trim());
            }else{
                criteria.andDataLevelEqualTo(1);
            }
        }

        example.setOrderByClause("sorts asc");

        return example;
    }


    /***
     * 获取数据字典 级联查询子集
     * @param dictTypeId  数据字典类型ID
     * @param keyword  关键字 字典名称 字典编码 字典值
     * @param isEnable  是否启用
     * @param dictList
     * @return
     */
    private List<TSysDictVO> subsetDictList(String dictTypeId, String keyword, Boolean isEnable, List<TSysDictType> dictTypeList, List<TSysDict> dictList){
        List<TSysDictVO>  dictVOList=new ArrayList<>();
        for(TSysDict dict:dictList){
            TSysDictVO dictVO=new TSysDictVO();
            BeanUtils.copyProperties(dict,dictVO);

            for (TSysDictType dictType:dictTypeList){
                if (dictVO.getDictTypeId().equals(dictType.getDictTypeId())){
                    dictVO.setDictTypeName(dictType.getDictTypeName());
                    break;
                }
            }

            TSysDictExample example=selectCascadeListDictExample(dict.getDictId(),dictTypeId,keyword,isEnable);

            long count=dictMapper.countByExample(example);
            if(count>0){
                dictVO.setChildren(subsetDictList(dictTypeId,keyword,isEnable,dictTypeList,dictMapper.selectByExample(example)));
            }
            dictVOList.add(dictVO);
        }
        return dictVOList;
    }

    @Override
    public List<TSysDictVO> selectCascadeDictList(String dictTypeId,String keyword,Boolean isEnable) {

        TSysDictExample example=selectCascadeListDictExample(null,dictTypeId,keyword,isEnable);
        List<TSysDictType> dictTypeList=dictTypeMapper.selectByExample(null);

        return subsetDictList(dictTypeId,keyword,isEnable,dictTypeList,dictMapper.selectByExample(example));
    }


    private List<TSysDict> fullCascadeDict(LinkedList<TSysDict> dictList, String dictId) {
        TSysDict dict=dictMapper.selectByPrimaryKey(dictId);
        dictList.add(0, dict);
        if(null!= dict.getParentId()&& !"".equals(dict.getParentId().trim())){
            fullCascadeDict(dictList,dict.getParentId());
        }
        return dictList;
    }

    @Override
    public List<TSysDict> findFullCascadeParent(String dictId) {
        return fullCascadeDict(new LinkedList<TSysDict>(),dictId);
    }





    @Override
    //@Cacheable(value = "monitor-early-warning:cache:2hours", key="'dictListByTypeId:'+#dictTypeId",unless="#result == null")
    public List<TSysDict> selectByDictTypeId(String dictTypeId) {
        TSysDictExample example=new TSysDictExample();
        example.createCriteria().andDictTypeIdEqualTo(dictTypeId.trim()).andIsEnableEqualTo(true);
        example.setOrderByClause("sorts asc");
        return dictMapper.selectByExample(example);
    }

    @Override
    public Map<String, String> getDictMapByDictTypeId(String dictTypeId) {
        List<TSysDict> dictList=this.selectByDictTypeId(dictTypeId);
        return dictList.stream().collect(Collectors.toMap(TSysDict::getDictId, TSysDict::getDictName));
    }

    @Override
    @Async
    public void updateSubDictLevel(String dictId) {
        TSysDict parentDict=dictMapper.selectByPrimaryKey(dictId);
        if (null!=parentDict){
            TSysDictType dictType=dictTypeMapper.selectByPrimaryKey(parentDict.getDictTypeId());
            if (dictType.getIsCascade()) {
                updateSubDictLevel(parentDict);
            }
        }
    }

    private void updateSubDictLevel(TSysDict parentDict) {
        TSysDictExample dictExample=new TSysDictExample();
        dictExample.createCriteria().andParentIdEqualTo(parentDict.getDictId());
        if (dictMapper.countByExample(dictExample)>0){

            TSysDict dict=new TSysDict();
            dict.setDataLevel(parentDict.getDataLevel()+1);
            dictMapper.updateByExampleSelective(dict,dictExample);
            List<TSysDict> subDictList=dictMapper.selectByExample(dictExample);
            for (TSysDict subDict:subDictList){
                updateSubDictLevel(subDict);
            }
        }
    }
}
